package com.nightpiter.model;

import static com.nightpiter.controller.log.Logger.log;
import static com.nightpiter.controller.log.Logger.logException;
import static com.nightpiter.controller.log.Logger.logProfilerBegin;
import static com.nightpiter.controller.log.Logger.logProfilerEnd;
import android.os.Handler;

import com.nightpiter.NightPiter;
import com.nightpiter.model.MetroModelState.Action;
import com.nightpiter.model.exceptions.BuilderException;
import com.nightpiter.model.reader.MetroModelReaderFactory;

/**
 * MVC's Model class
 * 
 * to instantiate this class use MetroModelBuilder's build method
 * 
 * @author Eldar Abusalimov (eldar.abusalimov@gmail.com)
 */
public class MetroModel {

	/**
	 * Application context
	 */
	private NightPiter context;

	/**
	 * the data currently loaded in the Model
	 */
	private MetroModelData data = new MetroModelData();

	/**
	 * current state of the Model
	 */
	private MetroModelState state = new MetroModelState();

	/**
	 * default constructor
	 * 
	 * @param context
	 *            the application context
	 */
	public MetroModel(NightPiter context) {
		this.context = context;
		log("Model instance created");
	}

	/**
	 * should be called after another MVC components created
	 */
	public void init() {
		log("Model init() call");
	}

	/**
	 * building method
	 * 
	 * package protected (should be called from MetroModelBuilder's build
	 * method)
	 * 
	 * @param data
	 */
	void build(MetroModelData data) {
		this.data = data;
	}

	/**
	 * loads a new model data
	 * 
	 * @param filePath
	 *            the file path; could be null - in this case the metro data
	 *            would be loaded from resources
	 */
	public void load(String filePath, Handler handler) {
		logProfilerBegin("reading the Model");
		this.state.action = Action.LOADING;
		this.state.resetAll(handler);
		try {
			MetroModelReaderFactory.getReader(this).readFromFile(filePath,
					this.getContext());
		} catch (BuilderException e) {
			logException(e);
		}
		this.state.action = Action.IDLE;
		this.state.setReady(true);
		logProfilerEnd("Model read completed");
	}

	/**
	 * loads a new model data
	 * 
	 * @param resId
	 *            resource id to load data from
	 */
	public void load(int resId, Handler handler) {
		logProfilerBegin("reading the Model");
		this.state.action = Action.LOADING;
		this.state.resetAll(handler);
		try {
			MetroModelReaderFactory.getReader(this).readFromResource(resId,
					this.getContext());
		} catch (BuilderException e) {
			logException(e);
		}
		this.state.action = Action.IDLE;
		this.state.setReady(true);
		logProfilerEnd("Model read completed");
	}

	/**
	 * @return the state
	 */
	public MetroModelState getState() {
		return state;
	}

	/**
	 * @return the data
	 */
	public MetroModelData getData() {
		return data;
	}

	/**
	 * @return the context
	 */
	protected NightPiter getContext() {
		return context;
	}

}
